﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Text;

namespace CoolStuff
{
    public class Util
    {
        static public string serverUrl;

        #region Creds
        static public string O365Username = "";
        static public string O365Password = "";
        #endregion

        //static WebRequest req;
        HttpWebRequest req;
         System.Net.WebProxy proxy;
         public string fileName = "";
         public string acceptOverride = "";
         public string contentTypeOverride = "";
         public string methodOverride = "";
         public Hashtable headers = new Hashtable();

        //static WebRequest req;
        static public string username = "";
        static public string password = "";
        static public string domain = "";

        //sharepoint auth
        static public string accessToken = "";
        static public string rtFa = "";
        static public string fedAuth = "";
        static public bool isO365 = false;

         public bool allowRedirects = false;
         public string post;
         public string response;
         public string referer = "";
         CookieCollection cookieC;
         CookieContainer cc;
        public string cookies = "";
        public string location = "";
        public string statusCode = "";
        public string lastFileName = "";
         public string DoGet(string url, string cookie)
        {
            string response = "";
            try
            {
                req = (HttpWebRequest)HttpWebRequest.Create(url);
                req.Method = "GET";
                SetupHttpRequest(req);
                if (!string.IsNullOrEmpty(cookie))
                    req.Headers.Add(cookie);
                response = ProcessResponse(req);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return response;
        }
         public void SetupHttpRequest(HttpWebRequest req)
        {
            ServicePointManager.Expect100Continue = false;
            req.AllowAutoRedirect = allowRedirects;
            req.UseDefaultCredentials = true;
            if (isO365)
                req.UseDefaultCredentials = false;
            else
            {
                req.AuthenticationLevel = System.Net.Security.AuthenticationLevel.MutualAuthRequested;
                if (username.Length > 0 && password.Length > 0 && domain.Length > 0)
                    req.Credentials = new NetworkCredential(username, password, domain);
            }
            req.UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)";
            req.Timeout = 200000;
            if (proxy != null)
                req.Proxy = proxy;
            if (referer.Length > 0)
            {
                req.Referer = referer;
                referer = "";
            }

            if (req.Method == "POST" || req.Method == "PATCH")
            {
                if (contentTypeOverride.Length > 0)
                {
                    req.ContentType = contentTypeOverride;
                    contentTypeOverride = "";
                }
                else
                    req.ContentType = "application/x-www-form-urlencoded";
            }

            if (acceptOverride.Length > 0)
            {
                req.Accept = acceptOverride;
                acceptOverride = "";
            }
            else
                req.Accept = "*/*";

            foreach (string key in headers.Keys)
            {
                req.Headers.Add(key.ToString(), headers[key].ToString());
            }
            headers = new Hashtable();

            req.Headers.Add("Accept-Language: en-us");
            req.Headers.Add("Accept-Encoding: gzip, deflate");
        }
        public string ParseValue(string line, string startToken, string endToken)
        {
            if (startToken == null)
            {
                return "";
            }
            try
            {
                if (startToken == "")
                {
                    return line.Substring(0, line.IndexOf(endToken));
                }
                else
                {
                    string rtn = line.Substring(line.IndexOf(startToken));
                    return rtn.Substring(startToken.Length, rtn.IndexOf(endToken, startToken.Length) - startToken.Length).Replace("\n", "").Replace("\t", "");
                }
            }
            catch (Exception ex)
            {
                //Logger.LogGeneralMessage("Tried to find [" + startToken + "] in [" + line + "]");
            }
            finally
            {
            }
            return "";
        }
        public void AuthenticateO365(string url, string username, string password)
        {
            serverUrl = url;
            //start on auth page 
            string authUrl = url + "/_layouts/15/Authenticate.aspx";
            allowRedirects = false;
            DoGet(authUrl, "");
            Uri uri = new Uri(url);
            //redirect to the forms page
            DoGet(uri.Scheme + "://" + uri.Host + "/" + location, "");
            //redirect to the O365 login
            string html = DoGet(location, "");
            string mspOK = ParseValue(cookies, "MSPOK=", ";");
            cc = new CookieContainer();
            cc.Add(new Cookie("MSPOK", mspOK, "/", "login.microsoftonline.com"));
            string ppft = html.Remove(0, html.IndexOf("PPFT"));
            ppft = ppft.Remove(0, ppft.IndexOf("value") + 7);
            ppft = ppft.Substring(0, ppft.IndexOf("\""));
            string postUrl = html.Remove(0, html.IndexOf("post.srf?") + 9);
            postUrl = postUrl.Substring(0, postUrl.IndexOf("\""));
            //string wctx = posturl.Remove(0, posturl.IndexOf("wctx"));
            //wctx = wctx.Substring(0, wctx.IndexOf("&"));
            url = "https://login.microsoftonline.com/ppsecure/post.srf?" + postUrl;
            string post = "login=" + username + "&passwd=" + password + "&PPSX=PassportR&PPFT=" + ppft + "&n1=111950&n2=-1389325702000&n3=-1389325702000&n4=111952&n5=111952&n6=111952&n7=111952&n8=NaN&n9=111952&n10=112024&n11=112021&n12=112270&n13=112272&n14=113180&n15=41&n16=113269&n17=113269&n18=113276&n19=379.53448033278346&n20=1&n21=0&n22=0&n23=1&n24=35.764367179524925&n25=0&n26=0&n27=0&n28=0&n29=-1389325815165&n30=-1389325815165&n31=false&n32=false&type=11&LoginOptions=3&NewUser=1&idsbho=1&PwdPad=&sso=&vv=&uiver=1&i12=1&i13=Firefox&i14=26.0&i15=1920&i16=952";
            string response = this.DoWorkPost(url, post, "");

            string t = response.Remove(0, response.IndexOf("id=\"t\""));
            t = t.Remove(0, t.IndexOf("value") + 7);
            t = t.Substring(0, t.IndexOf("\""));
            string action = ParseValue(response, "action=\"", "\"");
            post = "t=" + t;
            DoWorkPost(action, post, "");
            rtFa = ParseValue(cookies, "rtFa=", ";");
            fedAuth = ParseValue(cookies, "FedAuth=", ";");
        }
        public string DoWorkPost(string url, string inPost, string inCookies)
        {
            post = inPost;
            cookies = inCookies;
            return DoWorkPost(url);
        }
        public string ProcessResponse(HttpWebRequest req)
        {
            string response = "";
            try
            {
                HttpWebResponse res = (HttpWebResponse)req.GetResponse();
                statusCode = res.StatusCode.ToString();
                cookieC = res.Cookies;
                try
                {
                    string digest = res.Headers["X-RequestDigest"].ToString();
                    //Util.SetDigest(Util.serverUrl, digest);
                }
                catch (Exception ex)
                {
                }

                try
                {
                    location = res.Headers["Location"].ToString();
                }
                catch (Exception ex)
                {
                }
                try
                {
                    cookies = res.Headers["set-cookie"].ToString();
                }
                catch (Exception ex)
                {
                }
                fileName = "";
                long length = 0;
                try
                {
                    fileName = res.Headers["Content-Disposition"].ToString();
                    fileName = fileName.Replace("attachment; filename=", "");
                    length = res.ContentLength;
                }
                catch (Exception ex)
                {
                }
                if (fileName.Length > 0)
                {
                    // Define buffer and buffer size
                    int bufferSize = 2048;
                    byte[] buffer = new byte[bufferSize];
                    int bytesRead = 0;
                    // Read from response and write to file
                    Stream strm = res.GetResponseStream();
                    FileStream fileStream = System.IO.File.Create(@"c:\temp\" + fileName);
                    while ((bytesRead = strm.Read(buffer, 0, bufferSize)) != 0)
                    {
                        fileStream.Write(buffer, 0, bytesRead);
                    } // end while
                    fileStream.Close();
                    strm.Close();
                }
                else
                {
                    Stream responseStream = res.GetResponseStream();
                    if (res.ContentEncoding.ToLower().Contains("gzip"))
                        responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
                    else if (res.ContentEncoding.ToLower().Contains("deflate"))
                        responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
                    StreamReader reader = new StreamReader(responseStream, Encoding.Default);
                    response = reader.ReadToEnd();
                    res.Close();
                    responseStream.Close();
                    req = null;
                    proxy = null;
                }
            }
            catch (WebException ex)
            {
                HttpWebResponse res = (HttpWebResponse)ex.Response;
                Stream responseStream = res.GetResponseStream();
                if (res.ContentEncoding.ToLower().Contains("gzip"))
                    responseStream = new GZipStream(responseStream, CompressionMode.Decompress);
                else if (res.ContentEncoding.ToLower().Contains("deflate"))
                    responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
                StreamReader reader = new StreamReader(responseStream, Encoding.Default);
                response = reader.ReadToEnd();
                if (response.Contains("\"error\""))
                {
                    //CheckForError(response);
                }
            }
            catch (Exception ex)
            {
            }
            return response;
        }

         public string DoPost(string url, string postData, string cookie)
        {
            ASCIIEncoding encoding = new ASCIIEncoding();
            byte[] data = encoding.GetBytes(postData);
            return DoPost(url, data, cookie);
        }
         public string DoPost(string url, byte[] data, string cookie)
        {
            HttpWebRequest httpWReq = (HttpWebRequest)WebRequest.Create(url);
            httpWReq.UseDefaultCredentials = true;
            SetupHttpRequest(httpWReq);
            if (!string.IsNullOrEmpty(cookie))
                httpWReq.Headers.Add(cookie);
            httpWReq.Method = "POST";
            httpWReq.ContentLength = data.Length;
            httpWReq.ContentType = "application/x-www-form-urlencoded";

            if (acceptOverride.Length > 0)
            {
                httpWReq.Accept = acceptOverride;
                acceptOverride = "";
            }

            if (contentTypeOverride.Length > 0)
            {
                httpWReq.ContentType = contentTypeOverride;
                contentTypeOverride = "";
            }

            foreach (string key in headers.Keys)
            {
                req.Headers.Add(key.ToString(), headers[key].ToString());                
            }
            headers = new Hashtable();

            if (data.Length > 0)
            {
                using (Stream stream = httpWReq.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
            }
            string responseString = ProcessResponse(httpWReq);

            return responseString;
        }
        static public string GetAuthCookie()
        {
            string cookie = "";
            cookie = "Cookie: ";
            if (isO365)
            {
                cookie += "rtFa=" + rtFa + "; ";
            }
            cookie += "FedAuth=" + fedAuth + "; ";
            return cookie;
        }
        public string DoWorkPost(string url)
        {
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);

            if (methodOverride.Length > 0)
            {
                req.Method = methodOverride;
                methodOverride = "";
            }
            else
                req.Method = "POST";

            SetupHttpRequest(req);
            if (!string.IsNullOrEmpty(cookies))
                req.Headers.Add(cookies);
            else
                req.CookieContainer = cc;
            req.Headers.Add("Pragma", "no-cache");
            req.ServicePoint.Expect100Continue = false;
            ASCIIEncoding ascii = new ASCIIEncoding();
            byte[] postBytes = ascii.GetBytes(post);

            if (contentTypeOverride.Length > 0)
            {
                req.ContentType = contentTypeOverride;
                contentTypeOverride = "";
            }
            else
                req.ContentType = "application/x-www-form-urlencoded";

            req.ContentLength = postBytes.Length;
            // add post data to request
            Stream postStream = req.GetRequestStream();
            postStream.Write(postBytes, 0, postBytes.Length);
            postStream.Flush();
            postStream.Close();
            response = ProcessResponse(req);
            req = null;
            proxy = null;
            return response;
        }

        public void CreateUser(string twitterId)
        {
            string res = DoGet("https://portal.office.com", "");
            string url = location;

            res = DoGet(url, "");

            string ppsx = ParseValue(res, "name=\"PPSX\"", ">");
            ppsx = ParseValue(ppsx, "value=\"", "\"");

            string ppft = ParseValue(res, "name=\"PPFT\"", ">");
            ppft = ParseValue(ppft, "value=\"", "\"");
            ppft = System.Web.HttpUtility.UrlEncode(ppft);

            string action = ParseValue(res, "method=\"post\" action=\"", "\"");
            string MSPRequ = ParseValue(cookies, "MSPRequ=", ";");
            string MSPOK = ParseValue(cookies, "MSPOK=", ";");
            string cookie = "Cookie: " + "MSPOK=" + MSPOK + "; MSPRequ=" + MSPRequ + ";";

            referer = url;
            string post = "login=" + Util.O365Username + "&passwd=" + Util.O365Password + "&PPSX=" + ppsx + "&PPFT=" + ppft + "&n1=73802&n2=-1428783948000&n3=-1428783948000&n4=73802&n5=73802&n6=73802&n7=73802&n8=NaN&n9=73802&n10=73802&n11=73802&n12=73802&n13=73802&n14=74499&n15=860&n16=75469&n17=75470&n18=75473&n19=309.41407554678767&n20=1&n21=1&n22=1428784024008.637&n23=1&n24=597.8902118127439&n25=1&n26=0&n27=0&n28=0&n29=-1428784022448&n30=-1428784022448&n31=0&n32=0&n33=0&n34=0&n35=0&n36=0&n37=0&n38=0&n39=0&n40=1672.2318705713755&n41=1748.2978302119581&n42=1056.3810465462877&n43=1671.6592418806683&type=11&LoginOptions=2&NewUser=1&idsbho=1&PwdPad=&sso=&vv=&uiver=1&i12=1&i13=Firefox&i14=11.0&i15=1902&i16=923";
            res = DoPost(action, post, cookie);

            string wbids = ParseValue(res, "name=\"wbids\"", ">");
            wbids = ParseValue(wbids, "value=\"", "\"");
            wbids = System.Web.HttpUtility.UrlEncode(wbids);

            string wbid = ParseValue(res, "name=\"wbid\"", ">");
            wbid = ParseValue(wbid, "value=\"", "\"");
            wbid = System.Web.HttpUtility.UrlEncode(wbid);

            string token = ParseValue(res, "name=\"t\"", ">");
            token = ParseValue(token, "value=\"", "\"");
            token = System.Web.HttpUtility.UrlEncode(token);

            action = ParseValue(res, "action=\"", "\"");
            post = "wbids=" + wbids + "&wbid=" + wbid + "&t=" + token;
            res = DoPost(action, post, "");

            //get starting cookies
            //get ajaxsessionkey
            string RPSClearCT = ParseValue(cookies, "RPSClearCT=", ";");
            string sessionId = ParseValue(cookies, "s.SessID=", ";");
            string ajaxSessionKey = ParseValue(cookies, "s.AjaxSessionKey=", ";");

            cookie = "Cookie: s.AjaxSessionKey=" + ajaxSessionKey + "; s.RPSClearCT=" + RPSClearCT + "; s.SessID=" + sessionId + "; MH=MSFT";

            //go to default page
            res = DoPost("https://portal.office.com/default.aspx", "", cookie);

            //get new portal cookies
            string BecContext = ParseValue(cookies, "BecContext=", ";");
            string TagCacheKey = ParseValue(cookies, "TagCacheKey=", ";");
            string LoginUserTenantId = ParseValue(cookies, "LoginUserTenantId=", ";");
            string LoginContext = ParseValue(cookies, "LoginContext=", ";");
            string DisplayCulture = ParseValue(cookies, "DisplayCulture=", ";");

            cookie += ";s.BecContext=" + BecContext;
            cookie += ";s.TagCacheKey=" + TagCacheKey;
            cookie += ";s.LoginUserTenantId=" + LoginUserTenantId;
            cookie += ";s.LoginContext=" + LoginContext;
            cookie += ";s.DisplayCulture=" + DisplayCulture;

            res = DoGet("https://portal.office.com/admin/default.aspx ", cookie);
            string ConfigManagerLastBrsName = ParseValue(cookies, "s.ConfigManagerLastBrsName=", ";");
            string UnAuthUserCookie = ParseValue(cookies, "p.UnAuthUserCookie=", ";");

            cookie += ";s.ConfigManagerLastBrsName=" + ConfigManagerLastBrsName;
            cookie += ";p.UnAuthUserCookie=" + UnAuthUserCookie;

            headers.Add("AjaxSessionKey", ajaxSessionKey);
            headers.Add("X-Requested-With", "XMLHttpRequest");
            contentTypeOverride = "application/json; charset=utf-8";

            //create user
            post = "{\"properties\":{\"Parameters\":{\"__type\":\"JsonDictionaryOfanyType:#Microsoft.Office.CsmSdk\",\"DisplayNameFormat\":\"{FirstName} {LastName}\",\"Domains\":[\"cjg.onmicrosoft.com\"],\"DefaultDomain\":\"cjg.onmicrosoft.com\",\"ForceChangePassword\":true,\"SendPasswordEmailAddress\":\"givenscj@cjg.onmicrosoft.com\",\"IsAutoAssigned\":false,\"AutoAssignedProductName\":\"\",\"SkuItems\":[{\"__type\":\"JsonDictionaryOfanyType:#Microsoft.Office.CsmSdk\",\"AccountName\":\"cjg\",\"SkuPartNumber\":\"DEVELOPERPACK\",\"SkuTitle\":\"Microsoft Office 365 Developer\",\"SkuNumerOfLicensesText\":\"0 of 1 licenses available\",\"IsEnterprise\":false,\"IsSkuBuyMoreLinkVisible\":true,\"IsSkuSelected\":false,\"AvailableLicensesCount\":0,\"IsSkuEnabled\":false,\"IsCRMSku\":false,\"ServicePlans\":[\"OFFICESUBSCRIPTION\",\"MCOSTANDARD\",\"EXCHANGE_S_ENTERPRISE\",\"SHAREPOINTWAC_DEVELOPER\",\"SHAREPOINT_S_DEVELOPER\"]}],\"NoAnyLicense\":false,\"NewUserGoBackUrl\":\"\",\"SetPasswordVM\":{\"__msdisposeindex\":106,\"_initialized\":true},\"DisplayName\":\"" + twitterId + "\",\"UserPrincipalName\":\"" + twitterId + "@cjg.onmicrosoft.com\",\"AccountSkus\":\"[]\",\"LicenseOptions\":\"[]\",\"ShowLastNameFirst\":false}}}";
            res = DoPost("https://portal.office.com/EAdmin/DDIService/DDIService.svc/NewObject?schema=ActiveUser&AjaxSessionKey=" + ajaxSessionKey, post, cookie);

        }
    }
}
